﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using rusisControls.MVC.Helpers;

namespace System.Linq
{
    public static class LinqExtensions
    {
        /// <summary>
        /// Perform custom paging using LINQ to SQL
        /// </summary>
        /// <typeparam name="T">Type of the Datasource to be paged</typeparam>
        /// <typeparam name="TResult"></typeparam>
        /// <param name="obj">Object to be paged through</param>
        /// <param name="page">Page Number to fetch</param>
        /// <param name="pageSize">Number of rows per page</param>
        /// <param name="keySelector">Sorting Expression</param>
        /// <param name="asc">Sort ascending if true. Otherwise descending</param>
        /// <param name="rowsCount">Output parameter hold total number of rows</param>
        /// <returns>Page of result from the paged object</returns>
        public static IQueryable<T> Page<T, TResult>(this IQueryable<T> obj,
                                                    int? page,
                                                    int? pageSize,
                                                    System.Linq.Expressions.Expression<Func<T, TResult>> keySelector,
                                                    bool? asc,
                                                    out int rowsCount)
        {
            rowsCount = obj.Count();
            int innerRows = (page.HasValue && pageSize.HasValue) ? rowsCount - ((page.Value - 1) * pageSize.Value) : rowsCount;
            int rowsPerPage = pageSize.HasValue ? pageSize.Value : rowsCount;
            if (asc == null || asc == true)
            {
                return obj.OrderByDescending(keySelector).Take(innerRows)
                            .OrderBy(keySelector).Take(rowsPerPage).AsQueryable();
            }
            else
            {
                return obj.OrderBy(keySelector).Take(innerRows).
                            OrderByDescending(keySelector).Take(rowsPerPage).AsQueryable();
            }
        }


        /// <summary>
        /// Perform custom paging using LINQ to SQL
        /// </summary>
        /// <typeparam name="T">Type of the Datasource to be paged</typeparam>
        /// <typeparam name="TResult"></typeparam>
        /// <param name="obj">Object to be paged through</param>
        /// <param name="page">Page Number to fetch</param>
        /// <param name="pageSize">Number of rows per page</param>
        /// <param name="fieldName">Sorting filed name</param>
        /// <param name="asc">Sort ascending if true. Otherwise descending</param>
        /// <param name="rowsCount">Output parameter hold total number of rows</param>
        /// <returns>Page of result from the paged object</returns>
        public static IQueryable<T> Page<T, TResult>(this IQueryable<T> obj,
                                                    int? page,
                                                    int? pageSize,
                                                    string fieldName,
                                                    bool? asc,
                                                    out int rowsCount)
        {
            Func<T, object> keySelector = EFHelper.GetField<T>(fieldName);
            rowsCount = obj.Count();
            int innerRows = (page.HasValue && pageSize.HasValue) ? rowsCount - ((page.Value - 1) * pageSize.Value) : rowsCount;
            int rowsPerPage = pageSize.HasValue ? pageSize.Value : rowsCount;
            if (asc == null || asc == true)
            {
                return obj.OrderByDescending(keySelector).Take(innerRows)
                            .OrderBy(keySelector).Take(rowsPerPage).AsQueryable();
            }
            else
            {
                return obj.OrderBy(keySelector).Take(innerRows).
                            OrderByDescending(keySelector).Take(rowsPerPage).AsQueryable();
            }
        }



    }
}
